<?php
header ( 'Content-type:text/html; Charset=utf-8' );

// 支付宝公钥，账户中心->密钥管理->开放平台密钥，找到添加了支付功能的应用，根据你的加密类型，查看支付宝公钥
$alipayPublicKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqAseMOGItwdmilwmPbw2bhx1rCe1Gojaf/t+SU1mGDAXeh1HkxECAO0GRrSs7fpN5RQzc/cwRzBD/U5Gbq4VGJDkwCdyEaQct7++zp3exaUHiZ29Lq/MHeRnp/CQ5gETwdcYh7CBWvV0Z2VQwb4vfrEm4wNTAr9NG2TB5XUfdJwhCUugkyrY5DYIhKCNzxDR3rV4K8DUUI6YBf7bGasX4xH5h0F2kY223K/ihBzHaw18iuPxqT1kAFoCnNFysbtxbRWhPxRVljlD/xLO4qtnoNRSmDga9+YJrdyORL3WCPmijB9Qvt4n3nWAqbaV6A86WAOi2RVsy4pCGL68D3TVwIDAQAB';
$aliPay = new AlipayService ( $alipayPublicKey );
// 验证签名
$result = $aliPay->rsaCheck ( $_POST, $_POST ['sign_type'] );
if ($result === true) {
	// 处理你的逻辑，例如获取订单号$_POST['out_trade_no']，订单金额$_POST['total_amount']等
	// 程序执行完后必须打印输出“success”（不包含引号）。如果商户反馈给支付宝的字符不是success这7个字符，支付宝服务器会不断重发通知，直到超过24小时22分钟。一般情况下，25小时以内完成8次通知（通知的间隔频率一般是：4m,10m,10m,1h,2h,6h,15h）；
	var_log ( " recharge_notify time : " . date ( "T-m-d H:i:s" ), "log/" . date ( "Y-m-d" ) );
	var_log ( " recharge_notify result back : " . json_encode ( $_POST ), "log/" . date ( "Y-m-d" ) );
	post ( 'http://' . $_SERVER ['HTTP_HOST'] . '/zh/index.php?r=home/AliPay/rechargeNotify&is_pay=1', $_POST );
	echo 'success';
	exit ();
} else {
	var_log ( " recharge_notify time : " . date ( "T-m-d H:i:s" ), "log/" . date ( "Y-m-d" ) );
	var_log ( " recharge_notify result back : " . json_encode ( $_POST ), "log/" . date ( "Y-m-d" ) );
	echo 'error';
	exit ();
}
class AlipayService {
	// 支付宝公钥
	protected $alipayPublicKey;
	protected $charset;
	public function __construct($alipayPublicKey) {
		$this->charset = 'utf8';
		$this->alipayPublicKey = $alipayPublicKey;
	}
	
	/**
	 * 验证签名
	 */
	public function rsaCheck($params) {
		$sign = $params ['sign'];
		$signType = $params ['sign_type'];
		unset ( $params ['sign_type'] );
		unset ( $params ['sign'] );
		return $this->verify ( $this->getSignContent ( $params ), $sign, $signType );
	}
	function verify($data, $sign, $signType = 'RSA') {
		$pubKey = $this->alipayPublicKey;
		$res = "-----BEGIN PUBLIC KEY-----\n" . wordwrap ( $pubKey, 64, "\n", true ) . "\n-----END PUBLIC KEY-----";
		($res) or die ( '支付宝RSA公钥错误。请检查公钥文件格式是否正确' );
		
		// 调用openssl内置方法验签，返回bool值
		if ("RSA2" == $signType) {
			$result = ( bool ) openssl_verify ( $data, base64_decode ( $sign ), $res, version_compare ( PHP_VERSION, '5.4.0', '<' ) ? SHA256 : OPENSSL_ALGO_SHA256 );
		} else {
			$result = ( bool ) openssl_verify ( $data, base64_decode ( $sign ), $res );
		}
		// if(!$this->checkEmpty($this->alipayPublicKey)) {
		// //释放资源
		// openssl_free_key($res);
		// }
		return $result;
	}
	
	/**
	 * 校验$value是否非空
	 * if not set ,return true;
	 * if is null , return true;
	 */
	protected function checkEmpty($value) {
		if (! isset ( $value ))
			return true;
		if ($value === null)
			return true;
		if (trim ( $value ) === "")
			return true;
		return false;
	}
	public function getSignContent($params) {
		ksort ( $params );
		$stringToBeSigned = "";
		$i = 0;
		foreach ( $params as $k => $v ) {
			if (false === $this->checkEmpty ( $v ) && "@" != substr ( $v, 0, 1 )) {
				// 转换成目标字符集
				$v = $this->characet ( $v, $this->charset );
				if ($i == 0) {
					$stringToBeSigned .= "$k" . "=" . "$v";
				} else {
					$stringToBeSigned .= "&" . "$k" . "=" . "$v";
				}
				$i ++;
			}
		}
		unset ( $k, $v );
		return $stringToBeSigned;
	}
	
	/**
	 * 转换字符集编码
	 *
	 * @param
	 *        	$data
	 * @param
	 *        	$targetCharset
	 * @return string
	 */
	function characet($data, $targetCharset) {
		if (! empty ( $data )) {
			$fileType = $this->charset;
			if (strcasecmp ( $fileType, $targetCharset ) != 0) {
				$data = mb_convert_encoding ( $data, $targetCharset, $fileType );
				// $data = iconv($fileType, $targetCharset.'//IGNORE', $data);
			}
		}
		return $data;
	}
}
function var_log($data, $file_name) {
	if (! is_array ( $data ))
		$data ['the_log'] = $data;
	$file_name = $file_name . '_tem_log.php';
	$now_time = time ();
	$data ['log_add_date'] = date ( 'Y-m-d H:i:s', $now_time ) . "($now_time)";
	$data_string = var_export ( $data, true );
	if (file_exists ( $file_name ))
		file_put_contents ( $file_name, $data_string . PHP_EOL, FILE_APPEND );
	else
		file_put_contents ( $file_name, $data_string );
}
function post($url, $param = array()) {
	if (! is_array ( $param )) {
		throw new Exception ( "参数必须为array" );
	}
	$headers = array (
			'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/2008052906 Firefox/3.0' 
	);
	
	$ch = curl_init ( $url );
	curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
	curl_setopt ( $ch, CURLOPT_HEADER, true );
	curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, 120 );
	curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
	curl_setopt ( $ch, CURLOPT_POST, 1 ); // 设置为POST方式
	curl_setopt ( $ch, CURLOPT_POSTFIELDS, $param );
	curl_setopt ( $ch, CURLOPT_HEADER, 0 );
	$result = curl_exec ( $ch );
	curl_close ( $ch );
	return $result;
}
